package models

import (
	"cloudops/src/common"
	"encoding/json"
	"fmt"
	"gorm.io/gorm"
)

// 工单实例的评论结构体
type WorkOrderInstanceComment struct {
	UserNameTime string `json:"userNameTime" gorm:"-"`
	Comment      string `json:"comment" gorm:"-"  validate:"required,min=1"`
}

// 工单实例的执行历史结构体
type WorkOrderTimeLineItem struct {
	TimeAndNodeName   string `json:"timeAndNodeName"`
	DefineUserOrGroup string `json:"defineUserOrGroup"`
	ActualUser        string `json:"actualUser"  gorm:"-"`
	OutPut            string `json:"outPut" gorm:"-"` // 审批的结果 ，执行的输出
	EndTime           string `json:"endTime" gorm:"-"`
	IsPassOrIsSuccess bool   `json:"isPassOrIsSuccess" gorm:"-"` // 审批的结果 或执行的结果
	Color             string `json:"color"`
	TextAreaClass     string `json:"textAreaClass"` // 前端TextArea的样式 未完成的设置为空
	Disabled          bool   `json:"disabled"`      // 前端TextArea的样式  未完成的设置为true
}

// 工单详情结构体
type WorkOrderInstance struct {
	Model // 不用每次写ID 和 createAt了
	// 下面3个是用户填的
	Name string `json:"name" validate:"required,min=1,max=50" gorm:"uniqueIndex;type:varchar(100);comment:工单实例名称，支持使用通配符*进行模糊搜索" `
	// 用户填好的真实的 表单json字段
	ActualApiJsonData string `json:"actualApiJsonData"  gorm:"type:text;comment:用户填好的真实的 表单json字段;"`
	DesireFinishTime  string `json:"desireFinishTime"  gorm:"comment:期望完成时间"`
	// 需要关联1个模板 ，再通过模板去关联 审批流  表单设计
	TemplateId uint `json:"templateId"`
	UserID     uint

	// 流转 执行过程中需要更新的
	Status string `json:"status" gorm:"comment: 工单的状态 执行中 已完成 已拒绝"`

	CurrentFlowNode string `json:"currentFlowNode" gorm:"comment: 当前执行到哪个节点了"`

	// []FlowNode 有序数组 还要 记录每个节点的状态
	ActualFlowData string `json:"actualFlowData"  gorm:"type:text;comment:真实执行的历史记录 json，包含 每个审批的结果;"`
	FinalRunData   string `json:"finalRunData"  gorm:"type:text;comment:最终的执行结果"`
	Comments       string `json:"comments"  gorm:"type:text;comment:用户评论"`

	// 前端的字段
	TimeLineItems   []WorkOrderTimeLineItem `json:"timeLineItems" gorm:"-"`
	StatusChinese   string                  `json:"statusChinese" gorm:"-"`
	IsRelatedWithMe bool                    `json:"isRelatedWithMe" gorm:"-"` // 待我审批或者 待我执行的
	Template        *WorkOrderTemplate      `json:"template" gorm:"-"`
	Key             string                  `json:"key" gorm:"-"` //给前端表格
	CreateUserName  string                  `json:"createUserName" gorm:"-"`
}

// 创建工单实例
func (obj *WorkOrderInstance) CreateOneWorkOrderInstance() error {
	dbTemplate, err := GetWorkOrderTemplateById(int(obj.TemplateId))
	if err != nil {
		return err
	}

	obj.Status = common.WorkOrderInstanceStatusPendingApproval
	dbTemplate.FillFrontAllData()
	actualFlowData, _ := json.Marshal(dbTemplate.Process.FlowNodes)
	obj.ActualFlowData = string(actualFlowData)
	// 初始化创建的时候 下一个节点是 第一个
	obj.CurrentFlowNode = dbTemplate.Process.FlowNodes[0].DefineUserOrGroup
	obj.Comments = ""
	return DB.Create(obj).Error
}

// 获取我创建的工单实例,分页
func GetWorkOrderInstanceByCreateUserIdWithLimitOffset(userId uint, limit, offset int) (objs []*WorkOrderInstance, err error) {
	err = DB.Where("user_id = ?", userId).Limit(limit).Offset(offset).Find(&objs).Error
	return
}

// 获取我创建的工单实例的总数
func GetWorkOrderInstanceCountByCreateUserId(userId uint) int {
	var count int64
	DB.Table("work_order_instances").Where("user_id = ?", userId).Count(&count)
	return int(count)
}

// 获取所有的工单实力
func GetWorkOrderInstanceAll() (objs []*WorkOrderInstance, err error) {
	err = DB.Find(&objs).Error
	return
}

// 根据id获取工单实例,分页限制
func GetWorkOrderInstanceByIdsWithLimitOffset(ids []int, limit, offset int) (objs []*WorkOrderInstance, err error) {
	err = DB.Limit(limit).Offset(offset).Find(&objs, ids).Error
	return
}

// 状态是待审批的，当前节点是待我审批的。传入的值是用户的花名，或者相对应的组去做审批处理
func GetWorkOrderInstanceByStatusAndCurrentFlowNodesWithLimitOffset(status string, currentFlowNodes []string, limit, offset int) (objs []*WorkOrderInstance, count int64, err error) {
	err = DB.Debug().Where("status = ? and  current_flow_node IN ?", status, currentFlowNodes).Limit(limit).Offset(offset).Find(&objs).Limit(-1).
		Offset(-1).
		Count(&count).Error
	return
}

// 获取工单状态
func GetWorkOrderInstanceByStatusAndCurrentFlowNode(status, currentFlowNode string) (objs []*WorkOrderInstance, count int64, err error) {
	err = DB.Debug().Where("status = ? and  current_flow_node = ?", status, currentFlowNode).Find(&objs).Limit(-1).Offset(-1).Count(&count).Error
	return
}

// 获取未完成的工单
func GetWorkOrderInstanceUnfinished(statusArr []string) (objs []*WorkOrderInstance, count int64, err error) {
	err = DB.Where("status NOT IN ? ", statusArr).Find(&objs).Limit(-1).
		Offset(-1).
		Count(&count).Error
	return
}

// 给前端表格赋值
func (obj *WorkOrderInstance) FillFrontAllDataWorkOrderInstance() {
	dbUser, _ := GetUserById(int(obj.UserID))
	if dbUser != nil {
		obj.CreateUserName = dbUser.RealName
	}
	// 处理时间轴
	var actualFlowData []FlowNode
	json.Unmarshal([]byte(obj.ActualFlowData), &actualFlowData)
	timeLineItems := []WorkOrderTimeLineItem{
		{
			TimeAndNodeName: fmt.Sprintf("%v 新建工单",
				obj.CreatedAt.Format("2006-01-02 15:04:05"),
			),
			DefineUserOrGroup: fmt.Sprintf("创建人:%v", obj.CreateUserName),
			ActualUser:        fmt.Sprintf("实际执行人: %v", obj.CreateUserName),
			Color:             "green",
			OutPut:            "新建工单",
		},
	}
	for _, node := range actualFlowData {
		oneItem := WorkOrderTimeLineItem{
			TimeAndNodeName: fmt.Sprintf("%v %v ",
				node.EndTime,
				common.FLOW_TYPE_MAP[node.Type],
			),
			DefineUserOrGroup: fmt.Sprintf("候选人或组:%v", node.DefineUserOrGroup),
			ActualUser:        fmt.Sprintf("实际执行人: %v", node.ActualUser),
			OutPut:            node.OutPut,
			Color:             common.BOOL_COLOUR_MAP[node.IsPassOrIsSuccess],
		}
		timeLineItems = append(timeLineItems, oneItem)
	}

	obj.TimeLineItems = timeLineItems

	dbTemplate, _ := GetWorkOrderTemplateById(int(obj.TemplateId))

	if dbTemplate != nil {
		dbTemplate.FillFrontAllData()
		obj.Template = dbTemplate
	}

	obj.Key = fmt.Sprintf("%d", obj.ID)
	obj.StatusChinese = common.WorkOrderInstanceStatus_MAP[obj.Status]

}

// 根据id获取工单实例
func GetWorkOrderInstanceById(id int) (*WorkOrderInstance, error) {
	var dbObj WorkOrderInstance
	err := DB.Where("id = ?", id).First(&dbObj).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, fmt.Errorf("WorkOrderInstance不存在")
		}
		return nil, fmt.Errorf("数据库错误:%w", err)
	}
	return &dbObj, nil
}

// 更新工单实例
func (obj *WorkOrderInstance) UpdateOneWorkOrderInstance() error {
	return DB.Where("id = ?", obj.ID).Updates(obj).Error
}
